#region Imported namespaces
using System;
using System.Collections;
using System.Data;

using BO = PHSRAG.Insight21.BusinessObjects;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
using DataAccess = PHSRAG.Utility.DataAccess;
using GenerateKey = PHSRAG.Insight21.BusinessObjects.ModuleKey;
#endregion

namespace PHSRAG.Insight21.Humans
{
	/// <summary>
	/// A collection class to store device objects.
	/// 
	/// Provides functions to load the device object according to the search parameters and adds it to device collection and to get the list of device object.
	/// </summary>
	public class Devices:BO.BusinessObject
	{
		#region Private instance variables
		private ArrayList deviceList;
        private string sortBy;
        #endregion

		#region private constant cacheKey(Devices)
		private static string DevicesKey = GenerateKey.MakeKey("DevicesKey_B28C04CC-1ED1-4502-A2BF-A5C43F04E871",GenerateKey.Humans);
		private const string DeviceCollectionTableName = "DeviceCollection";
		#endregion

        #region SortByColumn constants
        /// <summary>
        /// Constants for setting the sortby column when getting the datarow arraylist
        /// </summary>
        public class SortByColumn
        {
            public const string ItemName = "sItemName";
            public const string GenericName = "sGenericName";
        }
        #endregion
        
        #region public properties
		/// <summary>Gets/Sets the list of devices </summary>
		public ArrayList DeviceList
		{
			get 
			{
				if (deviceList==null)
				{
					deviceList=GetList();
				}
				return deviceList;
			}
			set {deviceList=value;}
		}

        /// <summary>
        /// Gets/Sets the sort expression for this device collection
        /// </summary>
        public string SortBy
        {
            get { return sortBy; }
            set
            {
                if (sortBy != value)
                    deviceList = null;
                sortBy = value;
            }
        }
        #endregion

		#region public override methods

		#region caching
		/// <summary>
		/// Cache the current Object (Devices)using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(DevicesKey, this);
		}

		/// <summary>
		/// Remove an object(Devices) from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(DevicesKey);
		}
		#endregion
		/// <summary>
		/// Loads the dataContainer with the results(Devices)obtained using the search criteria
		/// </summary>
		/// <param name="rexConnection">Legacy database connection string</param>
		/// <param name="args">Search parameter values </param>
		public override void Load (string rexConnection,  params object[] args )
		{
			try
			{
				if (args.Length != 5)
				{
					throw new Exception("Mismatch in number of parameters(requires only 5 search parameters) passed for the load() of the devices object");
				}
				else 
				{
					System.Data.SqlClient.SqlParameter[] parameters =
						DataAccess.BuildSqlParameterArray(
						"@bContainsWord",	SqlDbType.Bit, Convert.ToBoolean(args[Convert.ToInt32(ColumnIndex.ContainsWord)]) );

					if ( string.Empty != (string)args[(int)ColumnIndex.ItemName] )
					{
						DataAccess.AppendToSqlParameterArray( ref parameters, "@sItemName", SqlDbType.VarChar, args[(int)ColumnIndex.ItemName] );
					}

					if ( string.Empty != (string)args[(int)ColumnIndex.GenericName] )
					{
						DataAccess.AppendToSqlParameterArray( ref parameters, "@sGenericName",	SqlDbType.VarChar, args[(int)ColumnIndex.GenericName] );
					}

					if ( string.Empty != (string)args[(int)ColumnIndex.Manufacturer] )
					{
						DataAccess.AppendToSqlParameterArray( ref parameters, "@sManufacturer",	SqlDbType.VarChar, args[(int)ColumnIndex.Manufacturer] );
					}

					if ( string.Empty != (string)args[(int)ColumnIndex.DeviceType] )
					{
						DataAccess.AppendToSqlParameterArray( ref parameters, "@sDeviceType",	SqlDbType.VarChar, args[(int)ColumnIndex.DeviceType] );
					}

					DataContainer = DataAccess.GetDataSet(rexConnection, "spIRBDeviceSearch", parameters );

					if(DataContainer.Tables.Count > 0)
					{
						DataContainer.Tables[0].TableName = DeviceCollectionTableName;
					}
					else
					{
						throw new Exception("Failed to load devices. The stored procedure returned incorrect results.");
					}
				}						
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to load devices.", ex);
			}
		}
		#endregion

		#region private methods
		/// <summary>Builds device objects for each row in the DataContainer and adds them to a arraylist</summary>
		/// <returns>Collection of device objects</returns>
		private ArrayList GetList()
		{
			ArrayList deviceList=null;
			if ((DataContainer!=null)&&(DataContainer.Tables.Count!=0))
			{
				deviceList=new ArrayList();

                DataTable devicesTable = null;
                if (sortBy != string.Empty)
                {
                    devicesTable = DataContainer.Tables[DeviceCollectionTableName];
                    devicesTable.DefaultView.Sort = sortBy;
                }
                for (int i = 0; i < devicesTable.DefaultView.Count; i++)
                {
                    DataRow dataRow = devicesTable.DefaultView[i].Row;
                    deviceList.Add(new Device(CachePolicy, dataRow));
                }
            }
			return deviceList;
			
		}
		#endregion

		#region Constructor
		/// <summary>
		/// Constructs a new Devices object based on the Cache Policy passed in as a parameter. 
		/// </summary>
		/// <param name="cachePolicy">available cahche policy</param>
		public Devices(ICachePolicy cachePolicy): base(cachePolicy)
		{		
		}
		#endregion

		#region Column Enumeration
		private enum ColumnIndex
		{
			ItemName,
			GenericName,
			Manufacturer,
			DeviceType,
			ContainsWord
		}
		#endregion
	}
}
